package com.study.javaOther.chain.utils;

import com.study.javaOther.chain.accoperation.Equals;

import java.util.Objects;

/**
 * @Name: MatcherUtil
 * @Description: java类作用描述
 * @Author: yn
 * @CreateDate: 2022/4/14 16:25
 * @Remark: 特殊说明
 * @Version: 1.0
 */
public class MatcherUtil {
    public static boolean wildcardMatching(String s, String p) {
        if(Objects.equals(s,p)){
            return true;
        }
        // i 用来记录s串检测的索引的位置
        int i = 0;
        // j 用来记录p串检测的索引的位置
        int j = 0;
        // 记录 待测串i的回溯点
        int ii = -1;
        // 记录 通配符*的回溯点
        int jj = -1;

        // 以s字符串的长度为循环基数，用i来记录s串当前的位置
        while (i < s.length()) {
            // 用j来记录p串的当前位置，检测p串中j位置的值是不是通配符*
            if (j < p.length() && p.charAt(j) == '*') {
                // 如果在p串中碰到通配符*，复制两串的当前索引，记录当前的位置，并对p串+1，定位到非通配符位置
                ii = i;
                jj = j;
                j++;
            }
            else if (j < p.length() // 检测p串是否结束
                    && (s.charAt(i) == p.charAt(j)   // 检测两串当前位置的值是否相等
                    || p.charAt(j) == '?')) { // 检测p串中j位置是否是单值通配符？
                // 如果此时p串还在有效位置上，那么两串当前位置相等或者p串中是单值通配符，表明此时匹配通过，两串均向前移动一步
                i++;
                j++;
            }
            else {
                // 如果在以上两种情况下均放行，表明此次匹配是失败的，那么此时就要明确一点，s串是否在被p串中的通配符*监听着，
                // 因为在首次判断中如果碰到通配符*，我们会将他当前索引的位置记录在jj的位置上，
                // 如果jj = -1 表明匹配失败，当前s串不在监听位置上
                if (jj == -1) return false;
                // 如果此时在s串在通配符*的监听下， 让p串回到通配符*的位置上继续监听下一个字符
                j = jj;
                // 让i回到s串中与通配符对应的当前字符的下一个字符上，也就是此轮匹配只放行一个字符
                i = ii + 1;
            }
        }

        // 当s串中的每一个字符都与p串中的字符进行匹配之后，对p串的残余串进行检查，如果残余串是一个*那么继续检测，否则跳出
        while (j < p.length() && p.charAt(j) == '*') j++;

        // 此时查看p是否已经检测到最后，如果检测到最后表示匹配成功，否则匹配失败
        return j == p.length();
    }

    public static void main(String args[]) {
        String s = "aabdsfgbcde";
        String p = "aab?bcde;a*gbcde;aab?e";
        Equals equals=new Equals();
        System.out.println(equals.match(s, p));
    }
}
